/**
 * 命名 首字母大写 驼峰
 */

import { useClipboard, usePermission } from "@vueuse/core";
import dayjs from "dayjs";
import { ElMessage } from "element-plus";

// 正则校验
export const RegTest = (value, type, info = "") => {
  let reg;

  // 数字
  if (type == "number") {
    reg = /^[0-9]+.?[0-9]*/;
    return reg.test(value);
  }
};

// 加密方式
export const Encryption = (value, type, info = "") => {
  /**
   * @param value 值
   * @param type  类型
   * @param info  【用于打印信息】
   */
  const encry = `${value}`;
  // 手机号码
  if (type == "phone")
    return encry.replace(/^(\d{3})\d{4}(\d{4})$/, "$1****$2");
  // 银行卡
  if (type == "bank_number")
    return encry.replace(/(?<=\d{4})\d+(?=\d{4})/, " **** **** ");
};

// 字符串分割
export const StrSplit = (str, mark, index) => {
  /*
   * str字符串 ”aaa：bbb：ccc“
   * mark分割符号 ：
   * index 下标
   * */
  const arr = str.split(mark);
  return arr[index];
};

// 数组对象降维
export const ArrayFlat = (arr, children = "children") => {
  /**
   * arr 数组
   * children 子键名 默认 为children
   */
  if (!arr.length) return [];
  if (arr instanceof Array) {
    for (let i = 0; i < arr.length; i++) {
      if (arr[i][children] && arr[i][children].length > 0) {
        arr = arr.slice(0, i + 1).concat(arr[i][children], arr.slice(i + 1));
      }
    }
  }
  return arr;
};
// 数组字符串降维
export const ArrayStrFlat = (arr) => {
  /**
   * arr 数组 [[1, 2], [3, 4], [5, 6]];
   */

  return arr.reduce((acc, cur) => {
    return acc.concat(cur);
  }, []);
};
// 数字逗号分割 123,456.7894
export const DigitSplit = (value, type = "money", decimal = 2) => {
  /*
   * value 值
   * type 类型 money 金额 其他数字
   * decimal 保留几位小数 默认两位
   * */

  if (type == "money" && !value) return "0.0000";
  if (type != "money" && !value) return 0.0;

  const str = value.toString();
  const int = StrSplit(str, ".", 0);
  let float = StrSplit(str, ".", 1);
  let floatafter = ".00";
  if (decimal == 4) {
    floatafter = ".0000";
  }

  // 0.6 ==> 0.60
  if (String(float).length == 1) {
    float = float + "0";
  }
  const reg = /(\d)(?=(?:\d{3})+$)/g;
  const newInt = int.toString().replace(reg, "$1,");
  return float
    ? `${newInt}.${float}`
    : `${newInt}${type == "money" ? floatafter : ""}`;
};

// 时间格式化
export const timeDayjs = (va, format = "YYYY-MM-DD HH:mm:ss") => {
  if (!va) return "--";

  // 时间默认
  if (va == "0000-00-00 00:00:00") return "--";
  if (va == "1970-01-01 00:00:00") return "--";

  const datetimeRegex = /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/;
  if (datetimeRegex.test(va)) {
    return va;
  } else {
    const date = new Date(Number(va));
    const year = date.getFullYear();
    const month = (date.getMonth() + 1).toString().padStart(2, "0");
    const day = date.getDate().toString().padStart(2, "0");
    const hours = date.getHours().toString().padStart(2, "0");
    const minutes = date.getMinutes().toString().padStart(2, "0");
    const seconds = date.getSeconds().toString().padStart(2, "0");

    const formattedDate = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
    return formattedDate;
  }
};
// 三位 ①逗号 123,4.123
export const ToThousands = (num) => {
  return num.toString().replace(/\d+/, function (n) {
    return n.replace(/(\d)(?=(?:\d{3})+$)/g, "$1,");
  });
};
// 数据强制保留小数 [默认两位]
export const ToDecimal = (x, num = 2) => {
  if (num == 0) return Number(x);

  // 倍数
  let multiple = Math.pow(100, num);

  let f = parseFloat(x);
  if (isNaN(f)) {
    return false;
  }
  f = Math.round(x * multiple) / multiple;
  let s = f.toString();
  let rs = s.indexOf(".");
  if (rs < 0) {
    rs = s.length;
    s += ".";
  }
  while (s.length <= rs + num) {
    s += "0";
  }
  return s;
};

/**
 * 'null' 'undefined' 'false' '' 'NaN' '{}' '[]'
 */
export const IsValueHave = (value) => {
  const _value = JSON.stringify(value);

  if (
    _value == '""' ||
    _value == "null" ||
    _value == null ||
    _value == "undefined" ||
    _value == undefined ||
    _value == "false" ||
    _value == "NaN" ||
    _value == "{}" ||
    _value == "[]"
  )
    return false;

  return true;
};

// 金钱格式化
export const MoneyFormat = (value, post = 4) => {
  if (!IsValueHave(value)) return "--";

  const money = ToDecimal(value, post);
  return ToThousands(money);
};
// 数量格式化
export const NumberFormat = (value, post = 2) => {
  if (!IsValueHave(value)) return "--";

  const number = ToDecimal(value, post);
  return ToThousands(number);
};
// 日期格式化
export const DateFormat = (value, format = "YYYY-MM-DD HH:mm:ss") => {
  if (!IsValueHave(value)) return "--";

  return dayjs(value).format(format);
};
// 字段级格式化
export const FieldFormat = (value, type = "", ratio = 2) => {
  if (!IsValueHave(value)) return "--";

  if (value == 0) value = value.toString();
  if (
    value == "" ||
    value == " " ||
    value == null ||
    value == undefined ||
    value == "{}" ||
    value == "[]"
  )
    return "--";

  // 默认
  if (!type) return value;

  // 是/否
  if (type == "boolean") {
    if (value == 0 || value == "0") return "否";
    if (value == 1 || value == "1") return "是";
  }

  // 数字
  if (type == "number") return NumberFormat(value, 0);
  // 金钱 默认保留两位 [money_eye 加密]
  if (type == "money" || type == "money_eye") return MoneyFormat(value, ratio);
  // 比率
  if (type == "ratio") return value ? `${value}%` : "0.00%";
  // 时间
  if (type == "time") return timeDayjs(value);
  //  手机号码
  if (type == "phone") return Encryption(value, type);
  //  手机号码
  if (type == "bank_number") return Encryption(value, type);
};

//@return 00:00:00 预计上传时间
export const EstimatedTime = (times = 0) => {
  if (typeof times === "number") {
    if (times <= 0) {
      return "00:00:00";
    } else {
      const hh = parseInt(String(times / 3600)); //小时
      const shh = times - hh * 3600;
      const ii = parseInt(String(shh / 60));
      const ss = shh - ii * 60;
      return `${ii}分${ss}秒`;
    }
  } else {
    return "00:00:00";
  }
};

// 默认 起始 00:00:00 结束 23:59:59
export const DefaultTime = [
  new Date(2000, 1, 1, 0, 0, 0),
  new Date(2000, 2, 1, 23, 59, 59),
];
// 默认
export const TimeFormat = "YYYY-MM-DD HH:mm:ss";

// 排除空值
export const ExcludeEmpty = async (value) => {
  let _value = [];

  const str = await value[value.length - 1].toString();

  if (!str) {
    _value = [""];
  } else {
    _value = value.filter((item) => {
      return RegTest(item, "number");
    });
  }
  return _value;
};

// 验证码随机数
export const RandomCode = (codeLength) => {
  function random(min, max) {
    return Math.floor(Math.random() * (max - min)) + min;
  }

  // codeLength 为随机字符长度
  let randomCode =
    "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
  randomCode = randomCode.split("");
  var res_code = "";
  while (res_code.length < codeLength) {
    res_code += randomCode[random(0, randomCode.length)];
  }
  // 返回随机字符集
  return res_code;
};

// 整数随机数 可以充当随机 编码/id
export const MathRandom = Math.floor(Math.random() * 1000000000000);

// 数组对象去重
export const FilterRepeat = (arr, key, arrType = "obj") => {
  if (!arr.length) return [];
  // 数组对象
  if (arrType == "obj") {
    const res = new Map();
    return arr.filter((item) => !res.has(item[key]) && res.set(item[key], 1));
  }
  // 数组字符串
  if (arrType == "str") {
    const result = arr.reduce((prev, item) => {
      if (!prev.includes(item)) {
        prev.push(item);
      }
      return prev;
    }, []);
    return result;
  }
};

// 转字符串
export const StrShift = (value) => {
  return value.toString();
};

// 根据code 返回 地址name
export const SeekAddressName = (code, arrdessOptions) => {
  // 例如 code [10001,1002,1003]

  const addressName = [];

  // 降维
  const array = ArrayFlat(arrdessOptions);

  // 通过编码查找对象名称
  for (let index = 0; index < array.length; index++) {
    const element = array[index];
    if (element.code == code[0]) addressName[0] = element.name;
    if (element.code == code[1]) addressName[1] = element.name;
    if (element.code == code[2]) addressName[2] = element.name;
  }

  return addressName;
};

// 遍历数组返回某个字段的集合
export const ReturnReduce = (list, key = "") => {
  return list.reduce((pre, el, index) => {
    pre.push(el[key]);
    return pre;
  }, []);
};

// 文件下载【通过长链接下载】
export const DownloadFile = (url, fileName) => {
  // 创建XMLHttpRequest对象
  var xhr = new XMLHttpRequest();

  xhr.open("GET", url, true);

  xhr.responseType = "blob";

  // 注册事件监听函数
  xhr.onload = function () {
    if (xhr.status === 200) {
      // 成功获取文件
      var blob = xhr.response;

      // 使用FileSaver.js库实现文件下载
      window.saveAs(blob, fileName);
    } else {
      // 获取文件失败
      console.log("Failed to download file");
    }
  };

  // 发送请求
  xhr.send();
};

// 根据月判定有多少天的方法
export const GetMonthLength = (date) => {
  const d = new Date(date);

  // 将日期设置为下月一号

  d.setMonth(d.getMonth() + 1);

  // d.setDate(1)

  // 获取本月最后一天

  d.setDate(d.getDate() - 1);

  return d.getDate();
};

// 数值展示 可加币别
export const YAxisDormatCurrency = (v, str = "") => {
  v = v.toString();
  if (v >= 100000000000) {
    return str + v.substring(0, 5) / 10 + "亿";
  } else if (v >= 10000000000) {
    return str + v.substring(0, 4) / 10 + "亿";
  } else if (v >= 1000000000) {
    return str + v.substring(0, 3) / 10 + "亿";
  } else if (v >= 100000000) {
    return str + v.substring(0, 2) / 10 + "亿";
  } else if (v >= 10000000) {
    return str + v.substring(0, 4) + "w";
  } else if (v >= 1000000) {
    return str + v.substring(0, 3) + "w";
  } else if (v >= 100000) {
    return str + v.substring(0, 2) + "w";
  } else if (v >= 10000) {
    return str + v.substring(0, 2) / 10 + "w";
  } else if (v >= 1000) {
    return str + v;
  } else {
    return str + v;
  }
};

// 数组等分 二维
export const ArraySliceLength = (array, subGroupLength) => {
  // array 代表一个数组
  // subGroupLength 代表数组里面的数组的length值
  let index = 0;
  let newArray = [];
  while (index < array.length) {
    newArray.push(array.slice(index, (index += subGroupLength)));
  }
  return newArray;
};

// 返回数组对象某键 形成新数组
export const ArrayOneValue = (_array, key) => {
  return _array.map((x) => {
    return x[key];
  }); // 生成数组
};

// 基础用户信息【本地缓存】
export const BaseUserInfo = () => {
  const storageJSON = localStorage.getItem("userInfo");
  const userInfo = JSON.parse(storageJSON);
  return userInfo;
};
/**
 * @description 复制数据
 * @param text
 */
export const HandleClipboard = (text) => {
  const { isSupported, copy } = useClipboard();
  if (!isSupported) {
    usePermission("clipboard-write");
  }
  copy(text)
    .then(() => {
      ElMessage(`拷贝${text}成功`);
    })
    .catch(() => {
      ElMessage(`拷贝${text}失败`);
    });
};
